#ifndef ABSTRACTTOOL_H
#define ABSTRACTTOOL_H
#include <QRadioButton>
#include <QPixmap>
#include <QPainter>
#include <QKeyEvent>
#include <QMouseEvent>
#include "Ptr.hpp"
#include "Work.h"


using namespace OOPUtils;

class AbstractTool : public QRadioButton
{

  Q_OBJECT

private:

  virtual void _canvasMousePressedEvent (QPoint loc, QMouseEvent * event) {}
  virtual void _canvasMouseReleasedEvent (QPoint loc, QMouseEvent * event) {}
  virtual void _canvasMouseMovedEvent (QPoint loc, QMouseEvent * event) {}
  virtual void _canvasPaintingEvent (QPainter & painter) {}
  virtual void _globalKeyReleasedEvent (QKeyEvent * event) {}
  virtual void _globalKeyPressedEvent (QKeyEvent * event) {}
  virtual void _startEvent () {}
  virtual void _finishEvent () {}

protected:

  Ptr< Work > __pWork;
  bool __isStarted;

public:

  AbstractTool (QWidget * parent) : QRadioButton (parent), 
    __isStarted (false), __pWork (NULL)
  {
    setCheckable (true);
    connect (this, SIGNAL (toggled(bool)), this, SLOT (handleToggled(bool)));
  }

  void start (Ptr< Work > pWork)
  {

    __pWork = pWork;

    // Connect tool with canvasViewport
    connect (__pWork->getViewportUI (), SIGNAL (mouseMoved (QMouseEvent *)),
      this, SLOT (handleCanvasMouseMoved (QMouseEvent *)));
    connect (__pWork->getViewportUI (), SIGNAL (mousePressed (QMouseEvent *)),
      this, SLOT (handleCanvasMousePressed (QMouseEvent *)));
    connect (__pWork->getViewportUI (), SIGNAL (mouseReleased (QMouseEvent *)),
      this, SLOT (handleCanvasMouseReleased (QMouseEvent *)));
    connect (__pWork->getViewportUI (), SIGNAL (painting (QPainter &)), 
      this, SLOT (handleCanvasPainting (QPainter &)));
    connect (this, SIGNAL (repaintViewport ()), 
      __pWork->getViewportUI (), SLOT (repaint ()));

    _startEvent ();
    
  }

  void finish ()
  {
    // Disconnect tool with canvasViewport
    disconnect (__pWork->getViewportUI (), SIGNAL (mouseMoved (QMouseEvent *)),
      this, SLOT (handleCanvasMouseMoved (QMouseEvent *)));
    disconnect (__pWork->getViewportUI (), SIGNAL (mousePressed (QMouseEvent *)),
      this, SLOT (handleCanvasMousePressed (QMouseEvent *)));
    disconnect (__pWork->getViewportUI (), SIGNAL (mouseReleased (QMouseEvent *)),
      this, SLOT (handleCanvasMouseReleased (QMouseEvent *)));
    disconnect ( __pWork->getViewportUI (), SIGNAL (painting (QPainter &)), 
      this, SLOT (handleCanvasPainting (QPainter &)));
    disconnect (this, SIGNAL (repaintViewport ()), 
      __pWork->getViewportUI (), SLOT (repaint ()));

    _finishEvent ();
  }

public slots:

  void handleCanvasMousePressed (QMouseEvent * event)
  {
    _canvasMousePressedEvent (
      __pWork->getViewportCtrl ()->viewportToImage (event->pos ()), event);
  }

  void handleCanvasMouseReleased (QMouseEvent * event)
  {
    _canvasMouseReleasedEvent (
      __pWork->getViewportCtrl ()->viewportToImage (event->pos ()), event);
  }

  void handleCanvasMouseMoved (QMouseEvent * event)
  {
    _canvasMouseMovedEvent (
      __pWork->getViewportCtrl ()->viewportToImage (event->pos ()), event);
  }

  void handleCanvasPainting (QPainter & painter)
  {
    _canvasPaintingEvent (painter);
  }

  void handleToggled (bool toggled)
  {
    if (toggled)
      emit triggered (this);
    else
      finish ();
  }


  void handleGlobalKeyPressed (Ptr< Work > pWork, QKeyEvent * event)
  {
    __pWork = pWork;
    _globalKeyPressedEvent (event);
  }

  void handleGlobalKeyReleased (Ptr< Work > pWork, QKeyEvent * event)
  {
    __pWork = pWork;
    _globalKeyReleasedEvent (event);
  }

signals:

  void triggered (AbstractTool * pTool);
  void repaintViewport ();

};

#endif // ABSTRACTTOOL_H
